using UnityEngine;
using UnityEngine.UIElements;
using System.Collections.Generic;
using Mono.Data.Sqlite;
using System.Linq;

public class DataPreviewUI : MonoBehaviour
{
    public static DataPreviewUI Instance { get; private set; }

    private VisualElement previewPanel;
    private DropdownField entityTypeDropdown;
    private TextField searchField;
    private ListView resultListView;
    private VisualElement detailPanel;

    private List<Entity> entities = new List<Entity>();
    private List<Relationship> relationships = new List<Relationship>();
    private List<Event> events = new List<Event>();

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
        }
        else
        {
            Destroy(gameObject);
        }
    }

    private void OnEnable()
    {
        var root = GetComponent<UIDocument>().rootVisualElement;

        previewPanel = root.Q<VisualElement>("PreviewPanel");
        entityTypeDropdown = root.Q<DropdownField>("EntityTypeDropdown");
        searchField = root.Q<TextField>("SearchField");
        resultListView = root.Q<ListView>("ResultListView");
        detailPanel = root.Q<VisualElement>("DetailPanel");

        entityTypeDropdown.choices = new List<string> { "Entity", "Relationship", "Event" };
        entityTypeDropdown.value = "Entity";
        entityTypeDropdown.RegisterValueChangedCallback(OnEntityTypeChanged);

        searchField.RegisterValueChangedCallback(OnSearchFieldChanged);

        resultListView.makeItem = () => new Label();
        resultListView.bindItem = (element, i) => (element as Label).text = resultListView.itemsSource[i].ToString();
        resultListView.onSelectionChange += OnResultSelectionChanged;

        previewPanel.style.display = DisplayStyle.None;
    }

    public void LoadDataFromSQLite(string sqliteFilePath)
    {
        string connectionString = "URI=file:" + sqliteFilePath;
        using (var connection = new SqliteConnection(connectionString))
        {
            connection.Open();

            LoadEntities(connection);
            LoadRelationships(connection);
            LoadEvents(connection);

            connection.Close();
        }

        previewPanel.style.display = DisplayStyle.Flex;
        UpdateResultList();
    }

  private void LoadEntities(SqliteConnection connection)
    {
        entities.Clear();
        using (var command = connection.CreateCommand())
        {
            command.CommandText = "SELECT * FROM Entities";
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    entities.Add(new Entity
                    {
                        Type = reader.GetString(0),
                        Name = reader.GetString(1),
                        Description = reader.GetString(2)
                    });
                }
            }
        }
    }

    private void LoadRelationships(SqliteConnection connection)
    {
        relationships.Clear();
        using (var command = connection.CreateCommand())
        {
            command.CommandText = "SELECT * FROM Relationships";
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    relationships.Add(new Relationship
                    {
                        From = reader.GetString(0),
                        To = reader.GetString(1),
                        RelationshipType = reader.GetString(2),
                        Attributes = JsonUtility.FromJson<Dictionary<string, object>>(reader.GetString(3))
                    });
                }
            }
        }
    }

    private void LoadEvents(SqliteConnection connection)
    {
        events.Clear();
        using (var command = connection.CreateCommand())
        {
            command.CommandText = "SELECT * FROM Events";
            using (var reader = command.ExecuteReader())
            {
                while (reader.Read())
                {
                    events.Add(new Event
                    {
                        Type = reader.GetString(0),
                        Name = reader.GetString(1),
                        Participants = JsonUtility.FromJson<List<string>>(reader.GetString(2)),
                        Location = reader.GetString(3),
                        Description = reader.GetString(4)
                    });
                }
            }
        }
    }

    private void OnEntityTypeChanged(ChangeEvent<string> evt)
    {
        UpdateResultList();
    }

    private void OnSearchFieldChanged(ChangeEvent<string> evt)
    {
        UpdateResultList();
    }

  private void UpdateResultList()
    {
        string searchText = searchField.value.ToLower();
        List<object> filteredResults = new List<object>();

        switch (entityTypeDropdown.value)
        {
            case "Entity":
                filteredResults = entities
                    .Where(e => e.Name.ToLower().Contains(searchText) || e.Type.ToLower().Contains(searchText))
                    .Cast<object>().ToList();
                break;
            case "Relationship":
                filteredResults = relationships
                    .Where(r => r.From.ToLower().Contains(searchText) || r.To.ToLower().Contains(searchText) || r.RelationshipType.ToLower().Contains(searchText))
                    .Cast<object>().ToList();
                break;
            case "Event":
                filteredResults = events
                    .Where(e => e.Name.ToLower().Contains(searchText) || e.Type.ToLower().Contains(searchText))
                    .Cast<object>().ToList();
                break;
        }

        resultListView.itemsSource = filteredResults;
        resultListView.Rebuild();
    }

    private void OnResultSelectionChanged(IEnumerable<object> selectedItems)
    {
        if (selectedItems.Any())
        {
            object selectedItem = selectedItems.First();
            UpdateDetailPanel(selectedItem);
        }
        else
        {
            detailPanel.Clear();
        }
    }

    private void UpdateDetailPanel(object selectedItem)
    {
        detailPanel.Clear();

        if (selectedItem is Entity entity)
        {
            AddDetailItem("类型", entity.Type);
            AddDetailItem("名称", entity.Name);
            AddDetailItem("描述", entity.Description);

            var relatedEvents = events.Where(e => e.Participants.Contains(entity.Name)).ToList();
            if (relatedEvents.Any())
            {
                AddDetailItem("相关事件", string.Join(", ", relatedEvents.Select(e => e.Name)));
            }
        }
        else if (selectedItem is Relationship relationship)
        {
            AddDetailItem("从", relationship.From);
            AddDetailItem("到", relationship.To);
            AddDetailItem("关系类型", relationship.RelationshipType);
            foreach (var attr in relationship.Attributes)
            {
                AddDetailItem(attr.Key, attr.Value.ToString());
            }
        }
        else if (selectedItem is Event evt)
        {
            AddDetailItem("类型", evt.Type);
            AddDetailItem("名称", evt.Name);
            AddDetailItem("参与者", string.Join(", ", evt.Participants));
            AddDetailItem("地点", evt.Location);
            AddDetailItem("描述", evt.Description);
        }
    }

    private void AddDetailItem(string label, string value)
    {
        var container = new VisualElement();
        container.style.flexDirection = FlexDirection.Row;
        container.style.justifyContent = Justify.SpaceBetween;

        var labelElement = new Label(label + ":");
        labelElement.style.width = 100;
        container.Add(labelElement);

        var valueElement = new Label(value);
        valueElement.style.flexGrow = 1;
        container.Add(valueElement);

        detailPanel.Add(container);
    }
}